package com.imdroid.lite.activities;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.GeoPoint;
import com.baidu.mapapi.ItemizedOverlay;
import com.baidu.mapapi.LocationListener;
import com.baidu.mapapi.MKLocationManager;
import com.baidu.mapapi.MapActivity;
import com.baidu.mapapi.MapController;
import com.baidu.mapapi.MapView;
import com.baidu.mapapi.MyLocationOverlay;
import com.baidu.mapapi.Overlay;
import com.baidu.mapapi.OverlayItem;
import com.baidu.mapapi.Projection;
import com.imdroid.lite.IMDroid;
import com.imdroid.lite.R;
import com.imdroid.lite.process.ProcessFactory;
import com.imdroid.lite.process.UserProcess;

public class CarLocationActivity extends MapActivity implements
		LocationListener {
	/**
	 * The tag of the CarLocationActivity
	 */
	private static String TAG = "CarLocationActivity";
	/**
	 * The mao view
	 */
	private MapView mapView;
	/**
	 * The map controller
	 */
	private MapController mapController;
	/**
	 * The overy lay of the my location
	 */
	private MyLocationOverlay myLocationOverlay;
	/**
	 * The location manager
	 */
	private MKLocationManager locationManager;
	/**
	 * The map manager
	 */
	private BMapManager bMapManager;

	private Button btnCurrent, btnLastWeek, btnLastTwoWeek;
	/**
	 * if set once cencenter already
	 */
	private boolean onceCenter = false;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onCreate(android.os.Bundle)
	 */
	public void onCreate(Bundle bdl) {
		super.onCreate(bdl);
		setContentView(R.layout.car_location);

		// 初始化地图
		IMDroid app = (IMDroid) this.getApplication();
		bMapManager = app.mBMapMan;
		super.initMapActivity(IMDroid.getAppContext().mBMapMan);
		mapView = (MapView) findViewById(R.id.mapView);
		mapView.setBuiltInZoomControls(true);
		// 设置中心
		mapController = mapView.getController();
		mapController.setZoom(15);
		IMDroid.getAppContext().mBMapMan.start();
		// 添加图层
		myLocationOverlay = new MyLocationOverlay(this, mapView);
		myLocationOverlay.enableMyLocation();
		myLocationOverlay.enableCompass();
		mapView.getOverlays().add(myLocationOverlay);

		// getButton
		btnCurrent = (Button) findViewById(R.id.btn_current);
		btnLastWeek = (Button) findViewById(R.id.btn_lastweek);
		btnLastTwoWeek = (Button) findViewById(R.id.btn_lasttwoweek);

		btnCurrent
				.setBackgroundResource(R.drawable.time_disable_range_selector);
		btnLastTwoWeek
				.setBackgroundResource(R.drawable.time_disable_range_selector);
		btnLastWeek
				.setBackgroundResource(R.drawable.time_disable_range_selector);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onDestroy()
	 */
	protected void onDestroy() {
		IMDroid app = (IMDroid) this.getApplication();
		if (app.mBMapMan != null)
			app.mBMapMan.stop();
		super.onDestroy();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onPause()
	 */
	protected void onPause() {
		IMDroid app = (IMDroid) this.getApplication();
		if (app.mBMapMan != null)
			app.mBMapMan.stop();

		if (locationManager != null)
			locationManager.removeUpdates(this);
		super.onPause();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#onResume()
	 */
	protected void onResume() {
		IMDroid app = (IMDroid) this.getApplication();
		if (app.mBMapMan != null)
			app.mBMapMan.start();

		locationManager = bMapManager.getLocationManager();
		locationManager.requestLocationUpdates(this);

		super.onResume();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.baidu.mapapi.MapActivity#isRouteDisplayed()
	 */
	protected boolean isRouteDisplayed() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.baidu.mapapi.LocationListener#onLocationChanged(android.location.
	 * Location)
	 */
	public void onLocationChanged(Location location) {
		if (location != null && !onceCenter) {
			final GeoPoint pt = new GeoPoint(
					(int) (location.getLatitude() * 1000000),
					(int) (location.getLongitude() * 1000000));
			mapController.setCenter(pt);
			onceCenter = true;
		}
	}

	/**
	 * 车机现在的位置
	 * 
	 * @param view
	 *            the button of the current position
	 */
	public void current(View view) {
		(new MyLocationTask()).execute();
		btnCurrent.setBackgroundResource(R.drawable.time_active_range_selector);
		btnLastTwoWeek
				.setBackgroundResource(R.drawable.time_disable_range_selector);
		btnLastWeek
				.setBackgroundResource(R.drawable.time_disable_range_selector);
	}

	/**
	 * 过去一周车的轨迹
	 * 
	 * @param view
	 *            the button
	 */
	public void lastWeek(View view) {
		(new MyPathTask()).execute(2);

		btnCurrent
				.setBackgroundResource(R.drawable.time_disable_range_selector);
		btnLastTwoWeek
				.setBackgroundResource(R.drawable.time_disable_range_selector);
		btnLastWeek
				.setBackgroundResource(R.drawable.time_active_range_selector);
	}

	/**
	 * 遥控车机拍照
	 * 
	 * @param view
	 *            the button
	 */
	public void takePicture(View view) {
		(new TakePictureTask()).execute();
	}

	/**
	 * 返回
	 * 
	 * @param view
	 *            the button of back
	 */
	public void back(View view) {
		finish();
	}

	protected void generateOverlay(Map<String, List<GeoPoint>> mapPaths) {

		if (mapPaths == null || mapPaths.size() == 0)
			return;

		Drawable marker = this.getResources().getDrawable(
				R.drawable.map_car_point);

		marker.setBounds(0, 0, marker.getIntrinsicWidth(),
				marker.getIntrinsicHeight());

		List<Overlay> mapOverlays = mapView.getOverlays();
		mapOverlays.clear();
		if (locationManager != null)
			locationManager.removeUpdates(this);

		Log.d(TAG, mapPaths.size() + "");
		int i = 0;
		GeoPoint lastPoint = null;
		for (String pathId : mapPaths.keySet()) {
			CarPathOverlay overlay = new CarPathOverlay(marker, i);
			List<GeoPoint> lstTemp = (List<GeoPoint>) mapPaths.get(pathId);
			// if (i == 0) {
			lastPoint = lstTemp.get(0);
			// }

			for (GeoPoint geoPoint : lstTemp) {
				OverlayItem overlayItem = new OverlayItem(geoPoint, "", "");
				overlay.addOverlay(overlayItem);
				// mapView.getController().setCenter(geoPoint);

			}
			mapOverlays.add(overlay);
			++i;
		}
		if (lastPoint != null) {
			mapView.getController().setCenter(lastPoint);
		}
	}

	/**
	 * The location and TIME
	 * 
	 */
	public static class LocationAndTime {
		public GeoPoint location;
		public Date time;

		public LocationAndTime(GeoPoint location, Date time) {
			this.location = location;
			this.time = time;
		}

	}

	/**
	 * The asnyc task of the checking my location.
	 * 
	 */
	private class MyLocationTask extends AsyncTask<Object, Void, Exception> {
		/**
		 * The dialog of process
		 */
		ProgressDialog progressDialog;
		/**
		 * The context
		 */
		Context context = CarLocationActivity.this;
		/**
		 * The location and time
		 */
		private LocationAndTime myCarLocation = null;

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPreExecute()
		 */
		protected void onPreExecute() {
			progressDialog = ProgressDialog.show(context, context
					.getResources().getString(R.string.car_wait_title), context
					.getResources().getString(R.string.car_wait_searching));
			progressDialog.show();
			progressDialog.setCancelable(true);

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#doInBackground(Params[])
		 */
		protected Exception doInBackground(Object... params) {
			UserProcess process = (UserProcess) ProcessFactory
					.getProcess(UserProcess.class);
			try {
				myCarLocation = process.getDeviceLocation(IMDroid.getUser());
				return null;
			} catch (Exception e) {
				return e;
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
		 */
		@SuppressLint("SimpleDateFormat")
		protected void onPostExecute(Exception result) {
			super.onPostExecute(result);
			progressDialog.dismiss();

			if (result != null) {
				String errorMessage = result.getMessage();
				Toast.makeText(context, errorMessage, Toast.LENGTH_SHORT)
						.show();

			} else {
				if (myCarLocation != null && myCarLocation.location != null) {
					CarCurrentLocationOverlay itemOverlay = new CarCurrentLocationOverlay(
							myCarLocation.location);
					// 显示时间
					mapView.getOverlays().clear();
					mapView.getOverlays().add(itemOverlay);
					// 设置屏幕中心
					mapController.setCenter(myCarLocation.location);
					mapController.setZoom(18);
					mapView.invalidate();
					// Toast更新时间
					if (myCarLocation.time != null) {
						SimpleDateFormat sdf = new SimpleDateFormat(
								"yyyy-MM-dd HH:mm:ss");

						String message = context.getString(
								R.string.car_loc_time).replace("%1%",
								sdf.format(myCarLocation.time) + "");

						Toast.makeText(context, message, Toast.LENGTH_LONG)
								.show();
					}
				}
			}
		}
	}

	/**
	 * The task of the path
	 * 
	 */
	private class MyPathTask extends AsyncTask<Integer, Void, Exception> {
		/**
		 * The dialog of process
		 */
		private ProgressDialog progressDialog;
		/**
		 * The context
		 */
		private Context context = CarLocationActivity.this;
		/**
		 * The paths
		 */
		private Map<String, List<GeoPoint>> paths;

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPreExecute()
		 */
		protected void onPreExecute() {
			progressDialog = ProgressDialog.show(context, context
					.getResources().getString(R.string.car_wait_title), context
					.getResources().getString(R.string.car_wait_searching));
			progressDialog.show();
			progressDialog.setCancelable(true);

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#doInBackground(Params[])
		 */
		protected Exception doInBackground(Integer... params) {
			UserProcess process = (UserProcess) ProcessFactory
					.getProcess(UserProcess.class);
			try {
				paths = process.getCarLocation(params[0]);
				return null;
			} catch (Exception e) {
				return e;
			}

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
		 */
		protected void onPostExecute(Exception result) {
			super.onPostExecute(result);
			progressDialog.dismiss();

			if (result != null) {
				String errorMessage = result.getMessage();
				Toast.makeText(context, errorMessage, Toast.LENGTH_SHORT)
						.show();
			} else if (paths != null) {
				generateOverlay(paths);
			}
		}
	}

	/**
	 * The task of the path
	 * 
	 */
	private class TakePictureTask extends AsyncTask<Void, Void, Exception> {
		/**
		 * The dialog of process
		 */
		private ProgressDialog progressDialog;
		/**
		 * The context
		 */
		private Context context = CarLocationActivity.this;
		/**
		 * The feed back phone number
		 */
		private String feedBackNumber = null;

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPreExecute()
		 */
		protected void onPreExecute() {
			progressDialog = ProgressDialog.show(context, context
					.getResources().getString(R.string.car_wait_title), context
					.getResources().getString(R.string.car_wait_searching));
			progressDialog.show();
			progressDialog.setCancelable(true);

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#doInBackground(Params[])
		 */
		protected Exception doInBackground(Void... params) {
			UserProcess process = (UserProcess) ProcessFactory
					.getProcess(UserProcess.class);
			try {
				feedBackNumber = process.takePicture(context);
				return null;
			} catch (Exception e) {
				return e;
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
		 */
		protected void onPostExecute(Exception result) {
			super.onPostExecute(result);
			progressDialog.dismiss();

			if (result != null) {
				String errorMessage = result.getMessage();
				Toast.makeText(context, errorMessage, Toast.LENGTH_SHORT)
						.show();
			} else if (feedBackNumber != null) {

				AlertDialog.Builder builder = new AlertDialog.Builder(context);
				builder.setIcon(android.R.drawable.ic_dialog_info);
				builder.setTitle(R.string.car_wait_title);
				builder.setMessage(feedBackNumber.trim().length() > 0 ? context
						.getString(R.string.car_take_picture_1).replace("%1%",
								feedBackNumber) : context
						.getString(R.string.car_take_picture_2));
				builder.setPositiveButton(R.string.car_wait_confirm, null);
				builder.create().show();
			}

		}

	}

	/**
	 * The overlay of the car current location
	 * 
	 */
	private class CarCurrentLocationOverlay extends Overlay {
		GeoPoint geoPoint = null;

		/**
		 * The point of the car current location
		 * 
		 * @param point
		 *            the point of the car current location
		 */
		public CarCurrentLocationOverlay(GeoPoint geoPoint) {
			super();
			this.geoPoint = geoPoint;

		}

		/**
		 * The paint
		 */
		private Paint paint = new Paint();
		/**
		 * The bitmap
		 */
		private Bitmap bmp = BitmapFactory.decodeResource(IMDroid
				.getAppContext().getResources(), R.drawable.map_car_friend);

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.Overlay#draw(android.graphics.Canvas,
		 * com.baidu.mapapi.MapView, boolean)
		 */
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			if (geoPoint != null) {
				Point point = mapView.getProjection().toPixels(geoPoint, null);

				canvas.drawBitmap(bmp, point.x - bmp.getWidth(),
						point.y - bmp.getHeight(), paint);
			}
		}
	}

	/**
	 * The overlay of destination
	 * 
	 */
	private class CarPathOverlay extends ItemizedOverlay<OverlayItem> {
		private ArrayList<OverlayItem> overlayItemList = new ArrayList<OverlayItem>();
		private int colors[] = { Color.BLUE, Color.RED, Color.GREEN };
		private int routeIndex;

		/**
		 * @param marker
		 *            the marker
		 * @param context
		 *            the context
		 */
		public CarPathOverlay(Drawable marker, int index) {
			super(boundCenterBottom(marker));
			this.routeIndex = index;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.ItemizedOverlay#draw(android.graphics.Canvas,
		 * com.baidu.mapapi.MapView, boolean)
		 */
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			super.draw(canvas, mapView, shadow);

			Projection projection = mapView.getProjection();
			for (int index = this.size() - 1; index > 0; index--) {
				OverlayItem overLayItemstart = getItem(index);
				OverlayItem overLayItemstop = getItem(index - 1);
				Point pointfrom = projection.toPixels(
						overLayItemstart.getPoint(), null);
				Point pointto = projection.toPixels(overLayItemstop.getPoint(),
						null);
				Paint paintLine = new Paint();
				paintLine.setColor(colors[routeIndex % colors.length]);
				paintLine.setStrokeWidth(5);
				canvas.drawLine(pointfrom.x, pointfrom.y, pointto.x, pointto.y,
						paintLine);
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.ItemizedOverlay#createItem(int)
		 */
		protected OverlayItem createItem(int i) {
			return overlayItemList.get(i);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.baidu.mapapi.ItemizedOverlay#size()
		 */
		public int size() {
			return overlayItemList.size();
		}

		/**
		 * @param overlayItem
		 */
		public void addOverlay(OverlayItem overlayItem) {
			overlayItemList.add(overlayItem);
			this.populate();
		}
	}
}
